package com.boluo.audit.service.impl;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

import com.boluo.audit.domain.AudBpmnInfo;
import com.boluo.audit.dto.AudCarPackageDTO;
import com.boluo.audit.dto.AuditedCarPackageDTO;
import com.boluo.audit.vo.HistoryAuditVO;
import com.boluo.business.domain.BusServiceItem;
import com.boluo.business.mapper.BusServiceItemMapper;
import com.boluo.business.service.IBusServiceItemService;
import com.boluo.common.constant.AuditConstants;
import com.boluo.common.constant.BusinessConstants;
import com.boluo.common.exception.ServiceException;
import com.boluo.common.utils.DateUtils;
import com.boluo.common.utils.SecurityUtils;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.CommentEntity;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskInfo;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.hibernate.validator.constraints.pl.REGON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.boluo.audit.mapper.AudCarPackageMapper;
import com.boluo.audit.domain.AudCarPackage;
import com.boluo.audit.service.IAudCarPackageService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 套餐审核Service业务层处理
 *
 * @author boluo
 * @date 2023-04-17
 */
@Service
public class AudCarPackageServiceImpl implements IAudCarPackageService {
    @Resource
    private AudCarPackageMapper audCarPackageMapper;
    @Resource
    private BusServiceItemMapper busServiceItemMapper;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;
    @Resource
    private RepositoryService repositoryService;

    /**
     * 查询套餐审核
     *
     * @param id 套餐审核主键
     * @return 套餐审核
     */
    @Override
    public AudCarPackage selectAudCarPackageById(Long id) {
        return audCarPackageMapper.selectAudCarPackageById(id);
    }

    /**
     * 查询套餐审核列表
     *
     * @param audCarPackage 套餐审核
     * @return 套餐审核
     */
    @Override
    public List<AudCarPackage> selectAudCarPackageList(AudCarPackage audCarPackage) {
        return audCarPackageMapper.selectAudCarPackageList(audCarPackage);
    }


    /**
     * 新增套餐审核
     *
     * @param audCarPackage 套餐审核
     * @return 结果
     */
    @Override
    public int insertAudCarPackage(AudCarPackage audCarPackage) {
        audCarPackage.setCreateTime(DateUtils.getNowDate());
        return audCarPackageMapper.insertAudCarPackage(audCarPackage);
    }

    /**
     * 修改套餐审核
     *
     * @param audCarPackage 套餐审核
     * @return 结果
     */
    @Override
    public int updateAudCarPackage(AudCarPackage audCarPackage) {
        return audCarPackageMapper.updateAudCarPackage(audCarPackage);
    }

    /**
     * 批量删除套餐审核
     *
     * @param ids 需要删除的套餐审核主键
     * @return 结果
     */
    @Override
    public int deleteAudCarPackageByIds(Long[] ids) {
        return audCarPackageMapper.deleteAudCarPackageByIds(ids);
    }

    /**
     * 删除套餐审核信息
     *
     * @param id 套餐审核主键
     * @return 结果
     */
    @Override
    public int deleteAudCarPackageById(Long id) {
        return audCarPackageMapper.deleteAudCarPackageById(id);
    }

    //使用 aud_car_package 表
    @Override
    @Transactional
    public int startAuditServiceItem(AudCarPackageDTO audCarPackagedto) {
        //参数校验

        // 获取服务项数据
        BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(audCarPackagedto.getId());

        // 设置流程变量值
        Map<String, Object> variables = new HashMap<>();
        variables.put("disCountPrice", busServiceItem.getDiscountPrice().longValue());
        variables.put("shopOwnerId", audCarPackagedto.getShopOwnerId());
        if (audCarPackagedto.getFinanceId() != null) {
            variables.put("financeId", audCarPackagedto.getFinanceId());
        }

        // 服务项id
        String businessKey = audCarPackagedto.getId() + "";
        // todo 流程定义key 写死后期有时间改
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(
                "bus_car_package",
                businessKey,
                variables
        );


        // 修改服务项状态
        busServiceItem.setAuditStatus(BusinessConstants.AUDIT_STATUS_PENDING);
        busServiceItemMapper.updateBusServiceItem(busServiceItem);


        // 往 aud_car_package 存数据
        AudCarPackage audCarPackage = new AudCarPackage();
        audCarPackage.setCreatorId(SecurityUtils.getUserId() + "");
        audCarPackage.setServiceItemId(busServiceItem.getId());
        audCarPackage.setServiceItemInfo(busServiceItem.getInfo());
        audCarPackage.setServiceItemName(busServiceItem.getName());
        audCarPackage.setServiceItemPrice(busServiceItem.getDiscountPrice());
        audCarPackage.setInfo(busServiceItem.getInfo());
        audCarPackage.setCreateTime(DateUtils.getNowDate());
        audCarPackage.setInstanceId(instance.getId());
        audCarPackage.setStatus(AuditConstants.CAR_PACKAGE_STATUS_PENDING);


        return audCarPackageMapper.insertAudCarPackage(audCarPackage);
    }


    //使用 aud_car_package 表
    @Override
    @Transactional
    public List<AudCarPackage> listToDoCarPackage() {
        String userId = SecurityUtils.getUserId().toString();
        List<Task> tasks = taskService.createTaskQuery()
                // 指定查询哪个用户
                .taskAssignee(userId)
                // 通过key 指定key指定流程
                .processDefinitionKey("bus_car_package")
                .list();

        if (tasks.size() == 0) {
            return Collections.emptyList();
        }


        // 获取流程实例id
        Set<String> processInstanceIdSet = tasks.stream()
                .map(TaskInfo::getProcessInstanceId)
                .collect(Collectors.toSet());
        if (processInstanceIdSet.size() == 0) {
            return Collections.emptyList();
        }

        return audCarPackageMapper.selectAudCarPackageByProcessInstanceIds(processInstanceIdSet);

    }


    @Override
    @Transactional
    public void auditAuditServiceItem(AuditedCarPackageDTO auditedCarPackageDTO) {
        boolean status = auditedCarPackageDTO.isStatus();
        // 获取流程实例id
        String processInstanceId = auditedCarPackageDTO.getProcessInstanceId();
        // 获取任务对象
        Task task = taskService.createTaskQuery()
                .taskAssignee(SecurityUtils.getUserId() + "")
                .processInstanceId(processInstanceId)
                .singleResult();

        String info = SecurityUtils.getUsername() + " 说:" + auditedCarPackageDTO.getInfo();
        // 添加审核配注
        taskService.addComment(task.getId(),
                task.getProcessInstanceId(),
                info);

        // 设置任务审核变量值
        Map<String, Object> variables = new HashMap<>();

        variables.put("shopOwner", status);
        // 审核任务
        taskService.complete(task.getId(), variables);

        if (status) {
            // 审核通过
            List<Task> list = taskService.createTaskQuery()
                    .processInstanceId(processInstanceId)
                    .list();
            // 判断后面还有没有任务
            if (list.isEmpty()) {
                // 把套餐审核信息和服务数据状态改成审核通过
                AudCarPackage audCarPackage = audCarPackageMapper.selectAudCarPackageByProcessInstanceId(processInstanceId);
                audCarPackage.setStatus(AuditConstants.CAR_PACKAGE_SUCCESS);
                audCarPackageMapper.updateAudCarPackage(audCarPackage);

                BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(audCarPackage.getServiceItemId());
                busServiceItem.setAuditStatus(BusinessConstants.AUDIT_STATUS_SUCCESS);
                busServiceItemMapper.updateBusServiceItem(busServiceItem);
            }

        } else {
            // 审核拒绝
            // 把套餐审核信息和服务数据状态改成审核拒绝
            AudCarPackage audCarPackage = audCarPackageMapper.selectAudCarPackageByProcessInstanceId(processInstanceId);
            audCarPackage.setStatus(AuditConstants.CAR_PACKAGE_FAIL);
            audCarPackageMapper.updateAudCarPackage(audCarPackage);

            BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(audCarPackage.getServiceItemId());
            busServiceItem.setAuditStatus(BusinessConstants.AUDIT_STATUS_FAIL);
            busServiceItemMapper.updateBusServiceItem(busServiceItem);

        }

    }

    @Override
    public InputStream getInputStream(String instanceId) {
        // 参数校验
        // 获取历史流程实例
        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(instanceId)
                .singleResult();


        // 查看流程图(高亮)
        // 这个对象用来画图的,内存中
        DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();


         // 多任务
        /*List<Task> tasks = taskService.createTaskQuery()
                .processInstanceId(instanceId)
                .list();
        List<String> activeActivityIds = new ArrayList<>();
        for (Task task : tasks) {
            List<String> activityIds = runtimeService.getActiveActivityIds(task.getExecutionId());
            activeActivityIds.addAll(activityIds);
        }*/
        // 单任务
        Task task = taskService.createTaskQuery()
                .processInstanceId(instanceId)
                .singleResult();
        List<String> activeActivityIds = Collections.emptyList();

        if (Objects.nonNull(task)) {
            // 获取当前任务运行到哪的节点
             activeActivityIds = runtimeService.getActiveActivityIds(task.getExecutionId());
        }

        // BpmnModel 对象 用来封装我们画的流程
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());

        // 画图,返回InputStream对象
        return generator.generateDiagram(
                // 封装流程图
                bpmnModel,
                // 哪个任务节点高亮
                activeActivityIds,
                Collections.emptyList(),
                // 字体
                "宋体",
                "宋体",
                "宋体");

    }

    @Override
    public List<AudCarPackage> listDoneCarPackage() {

        String userId = SecurityUtils.getUserId().toString();
        // 获取历史任务
        List<HistoricTaskInstance> hiTask = historyService.createHistoricTaskInstanceQuery()
                // 指定查询哪个用户
                .taskAssignee(userId)
                // 通过key 指定key指定流程
                .processDefinitionKey("bus_car_package")
                // 已经审核过的(就是有结束时间的)
                .finished()
                .list();


        if (hiTask.size() == 0) {
            return Collections.emptyList();
        }


        // 获取流程实例id
        Set<String> processInstanceIdSet = hiTask.stream()
                .map(TaskInfo::getProcessInstanceId)
                .collect(Collectors.toSet());
        if (processInstanceIdSet.size() == 0) {
            return Collections.emptyList();
        }

        return audCarPackageMapper.selectAudCarPackageByProcessInstanceIds(processInstanceIdSet);

    }

    @Override
    public List<HistoryAuditVO> queryAuditHistorys(String instanceId) {
        // 查询对应流程实例下的审核历史任务
        List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(instanceId)
                .list();
        if (taskInstanceList.size() == 0) {
            return Collections.emptyList();
        }
        return taskInstanceList.stream()
                .map(task ->{
                    HistoryAuditVO historyAuditVO = new HistoryAuditVO();
                    Date startTime = task.getStartTime();
                    Date endTime = task.getEndTime();

                    historyAuditVO.setTaskName(task.getName());
                    historyAuditVO.setStartTime(startTime);
                    // 这里是结束时间 可能会有空代表还没完成
                    historyAuditVO.setEndTime(endTime);
                    if (Objects.nonNull(endTime)) {
                        // 计算耗时 并封装到对象中
                        historyAuditVO.setDuration(DateUtils.getDatePoor(endTime, startTime));
                    }
                    // 查询任务对应的审核批注
                    // CommentEntity.TYPE_COMMENT 我们自己的
                    List<Comment> comments = taskService.getTaskComments(task.getId(), CommentEntity.TYPE_COMMENT);
                    if (comments.size() > 0) {
                        StringBuilder sb = new StringBuilder();
                        for (Comment comment : comments) {
                            sb.append(comment.getFullMessage()+"==");
                        }
                        historyAuditVO.setInfo(sb.toString());
                    }

                    return historyAuditVO;
                }).collect(Collectors.toList());



    }

    @Override
    public void cancelCarPackage(String instanceId) {
        // 校验当前状态可否被撤销

        // 删除流程实例
        runtimeService.deleteProcessInstance(instanceId,"我牛逼");

        // 修改状态
        AudCarPackage audCarPackage = audCarPackageMapper.selectAudCarPackageByProcessInstanceId(instanceId);
        audCarPackage.setStatus(AuditConstants.CAR_PACKAGE_REVOKE);
        audCarPackageMapper.updateAudCarPackage(audCarPackage);

        BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(audCarPackage.getServiceItemId());
        busServiceItem.setAuditStatus(BusinessConstants.AUDIT_STATUS_FAIL);
        busServiceItemMapper.updateBusServiceItem(busServiceItem);


    }

    /**
     * 没有使用 aud_car_package 表
     *
     * 查询流程信息图(任务节点高亮) (不用 bus_car_package)
     */

  /*  @Override
    public InputStream getInputStream(String serviceId) {
        // 参数校验

        // 获取历史流程实例
        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceBusinessKey(serviceId)
                .processDefinitionKey("bus_car_package")
                .singleResult();


        // 查看流程图(高亮)
        // 这个对象用来画图的,内存中
        DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();

        *//*
         多任务
        List<Task> tasks = taskService.createTaskQuery()
                .processInstanceId(instanceId)
                .list();
        List<String> activeActivityIds = new ArrayList<>();
        for (Task task : tasks) {
            List<String> activityIds = runtimeService.getActiveActivityIds(task.getExecutionId());
            activeActivityIds.addAll(activityIds);
        }*//*
        // 单任务
        Task task = taskService.createTaskQuery()
                .processInstanceId(processInstance.getId())
                .singleResult();
        List<String> activeActivityIds = Collections.emptyList();

        if (Objects.nonNull(task)) {
            // 获取当前任务运行到哪的节点
            activeActivityIds = runtimeService.getActiveActivityIds(task.getExecutionId());
        }

        // BpmnModel 对象 用来封装我们画的流程
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());

        // 画图,返回InputStream对象
        return generator.generateDiagram(
                // 封装流程图
                bpmnModel,
                // 哪个任务节点高亮
                activeActivityIds,
                Collections.emptyList(),
                // 字体
                "宋体",
                "宋体",
                "宋体");

    }*/
    /**
     * 没有使用 aud_car_package 表
     * @param busServiceItem 套餐审核列表
     * @return
     */
    /*@Override
    public List<BusServiceItem> selectAudCarPackageList(BusServiceItem busServiceItem) {
        // 查询历史实例表的所有流程实例
        List<HistoricProcessInstance> historicProcessInstances =
                historyService.createHistoricProcessInstanceQuery()
                        .processDefinitionKey("bus_car_package")
                        .list();

        if (historicProcessInstances.isEmpty()) {
            return Collections.emptyList();
        }

        // 使用stream 获取  businessKeys 集合
        List<String> businessKeys = historicProcessInstances.stream().map(HistoricProcessInstance::getBusinessKey)
                .collect(Collectors.toList());
        if (businessKeys.isEmpty()) {
            return Collections.emptyList();
        }
        // 批量查询

        return busServiceItemMapper.selectBusServiceItemByIds(businessKeys);
    }*/

    /**
     * 没有使用 aud_car_package 表
     * 新增流程实例
     * @return
     */
    /*@Override
    @Transactional
    public int startAuditServiceItem(AudCarPackageDTO audCarPackagedto) {
        //参数校验

        // 获取服务项数据
        BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(audCarPackagedto.getId());

        // 设置流程变量值
        Map<String, Object> variables = new HashMap<>();
        variables.put("disCountPrice", busServiceItem.getDiscountPrice().longValue());
        variables.put("shopOwnerId", audCarPackagedto.getShopOwnerId());
        if (audCarPackagedto.getFinanceId() != null) {
            variables.put("financeId", audCarPackagedto.getFinanceId());
        }

        // 服务项id
        String businessKey = audCarPackagedto.getId() + "";
        // todo 流程定义key 写死后期有时间改
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(
                "bus_car_package",
                businessKey,
                variables
        );

        // 修改服务项状态
        busServiceItem.setAuditStatus(BusinessConstants.AUDIT_STATUS_PENDING);

        return busServiceItemMapper.updateBusServiceItem(busServiceItem);

    }*/


    /**
     * 没有使用 aud_car_package 表
     * 查询 我的待办列表
     * @return
     */
    /*@Override
    @Transactional
    public List<BusServiceItem> listToDoCarPackage() {
        String userId = SecurityUtils.getUserId().toString();
        List<Task> tasks = taskService.createTaskQuery()
                // 指定查询哪个用户
                .taskAssignee(userId)
                // 通过key 指定key指定流程
                .processDefinitionKey("bus_car_package")
                .list();

        if (tasks.size() == 0) {
            return Collections.emptyList();
        }


        // 获取流程实例id
        List<String> processInstanceIds = tasks.stream()
                .map(TaskInfo::getProcessInstanceId)
                .collect(Collectors.toList());
        if (processInstanceIds.size() == 0) {
            return Collections.emptyList();
        }

        List<String> businessKeys = processInstanceIds.stream()
                .map(processInstanceId -> {
                    return historyService.createHistoricProcessInstanceQuery()
                            .processInstanceId(processInstanceId)
                            .singleResult();
                })
                .map(HistoricProcessInstance::getBusinessKey)
                .collect(Collectors.toList());
        return busServiceItemMapper.selectBusServiceItemByIds(businessKeys);

    }*/


    /**
     * 没有使用 aud_car_package 表
     * 审核流程定义功能
     * @return
     */
    /*@Override
    @Transactional
    public void auditAuditServiceItem(AuditedCarPackageDTO auditedCarPackageDTO) {
        boolean status = auditedCarPackageDTO.isStatus();
        // 获取服务项id
        String serivceId = auditedCarPackageDTO.getSerivceId();
        // 获取历史流程实例对象
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processDefinitionKey("bus_car_package")
                .processInstanceBusinessKey(serivceId)
                .singleResult();
        // 获取任务对象
        Task task = taskService.createTaskQuery()
                .taskAssignee(SecurityUtils.getUserId() + "")
                .processInstanceId(historicProcessInstance.getId())
                .singleResult();

        String info = SecurityUtils.getUsername() + " 说:" + auditedCarPackageDTO.getInfo();
        // 添加审核配注
        taskService.addComment(task.getId(),
                task.getProcessInstanceId(),
                info);

        // 设置任务审核变量值
        Map<String, Object> variables = new HashMap<>();

        variables.put("shopOwner", status);
        // 审核任务
        taskService.complete(task.getId(), variables);

        if (status) {
            // 审核通过
            List<Task> list = taskService.createTaskQuery()
                    .processInstanceId(historicProcessInstance.getId())
                    .list();
            // 判断后面还有没有任务
            if (list.isEmpty()) {
                // 服务数据状态改成审核通过
                BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(Long.parseLong(serivceId));
                busServiceItem.setAuditStatus(BusinessConstants.AUDIT_STATUS_SUCCESS);
                busServiceItemMapper.updateBusServiceItem(busServiceItem);
            }

        } else {
            // 审核拒绝
            // 把套餐审核信息和服务数据状态改成审核拒绝
            BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(Long.parseLong(serivceId));
            busServiceItem.setAuditStatus(BusinessConstants.AUDIT_STATUS_SUCCESS);
            busServiceItemMapper.updateBusServiceItem(busServiceItem);

        }
    }*/
}
